/**
 * &copy; 2006 NewInstance.it
 */
package it.newinstance.util.servlet;

import java.text.MessageFormat;
import java.util.regex.Pattern;
import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author Luigi R. Viggiano
 * @version $Id: HttpPatternFilter.java 155 2007-06-22 00:14:35Z luigi.viggiano $
 */
public abstract class HttpPatternFilter implements Filter {
    private Pattern pattern;

    private FilterConfig filterConfig;

    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
        String patternParam = filterConfig.getInitParameter("pattern");
        if (patternParam != null && patternParam.trim().length() > 0) {
            this.pattern = Pattern.compile(patternParam);
        }
    }

    public final void doFilter(ServletRequest servletRequest,
            ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        doFilter((HttpServletRequest) servletRequest,
                (HttpServletResponse) servletResponse, filterChain);
    }

    private void doFilter(HttpServletRequest request,
            HttpServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        if (patternMatches(request)) {
            filter(request, response, chain);
        } else {
            chain.doFilter(request, response);
        }
    }

    private boolean patternMatches(HttpServletRequest request) {
        if (pattern == null)
            return true;
        String path = request.getRequestURI().substring(
                request.getContextPath().length());
        boolean match = pattern.matcher(path).matches();
        if (match) {
            log(MessageFormat.format(
                "Filter match: requested path {0} matches regexp {1}.",
                path, pattern.pattern()));
        } else {
            log(MessageFormat.format(
                "Filtering out: requested path {0} doesn't match regexp {1}.",
                 path, pattern.pattern()));
        }
        return match;
    }

    public FilterConfig getFilterConfig() {
        return filterConfig;
    }

    protected void log(String message) {
        filterConfig.getServletContext().log(message);
    }

    protected void log(String message, Throwable throwable) {
        filterConfig.getServletContext().log(message, throwable);
    }

    protected abstract void filter(HttpServletRequest request,
            HttpServletResponse response, FilterChain chain)
            throws IOException, ServletException;

    public void destroy() {
    }
}
